/**
 * 
 */
package cn.springsoter.core.security.strategy.impl;

import java.io.FileNotFoundException;
import java.util.Map;
import java.util.Objects;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.google.common.collect.Maps;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import cn.springsoter.core.security.constant.SecurityConstant;
import cn.springsoter.core.security.strategy.ReadKeyStrategy;
import cn.springsoter.core.tool.utils.KeyStoreUtil;

/**
 * 从本地读取SM key
 * 
 * @author kevin
 *
 */
@Service
public class ReadSMKeyDefaultStrategy implements ReadKeyStrategy {

	private static final String SM_KEY_DEFAULT_CACHE = "SM_KEY_DEFAULT";
	private static final String SM_PUBLIC_KEY_CACHE = "SM_PUBLIC_KEY_CACHE";
	private static final String SM_PRIVATE_KEY_CACHE = "SM_PRIVATE_KEY_CACHE";
	private static Map<String, String> KEY_MAP = Maps.newConcurrentMap();
	private static Map<String, SM2> SM2_MAP = Maps.newConcurrentMap();
	
	/**
	 * 获取对称加密SM4的明文key
	 * 
	 */
	@Override
	public synchronized String readKey() throws FileNotFoundException{
		String key = KEY_MAP.get(SM_KEY_DEFAULT_CACHE);
		SM2 sm2 = SM2_MAP.get(SM_KEY_DEFAULT_CACHE);
		if(StringUtils.isBlank(key)) {
			
			String privateKeyStr = KeyStoreUtil.getKeyFromResources(SM_PRIVATE_KEY_CACHE, "sm/private.key");
			String publicKeyStr = KeyStoreUtil.getKeyFromResources(SM_PUBLIC_KEY_CACHE, "sm/public.key");
			
			if(StringUtils.isBlank(privateKeyStr) || StringUtils.isBlank(publicKeyStr)) {
	    		throw new FileNotFoundException("file: sm/private.key and sm/public.key not exist!");
	    	}
			
			if(Objects.isNull(sm2)) {
				sm2 = SmUtil.sm2(Base64.decode(privateKeyStr), Base64.decode(publicKeyStr));
				SM2_MAP.put(SM_KEY_DEFAULT_CACHE, sm2);
			}
			
			if(Objects.nonNull(sm2)) {
				//用sm2的私钥解密sm4的key
				key = sm2.decryptStr(SecurityConstant.SM4KEY, KeyType.PrivateKey, CharsetUtil.CHARSET_UTF_8);
				KEY_MAP.put(SM_KEY_DEFAULT_CACHE, key);
			}
		}
		return key;
	}
	
	/**
	 * 获取非对称加密SM2实例对象
	 * 
	 * @return
	 * @throws FileNotFoundException
	 */
	public synchronized SM2 getSm2Instance() throws FileNotFoundException{
		SM2 sm2 = SM2_MAP.get(SM_KEY_DEFAULT_CACHE);
		if(Objects.nonNull(sm2)) {
			return sm2;
		}
		String privateKeyStr = KeyStoreUtil.getKeyFromResources(SM_PRIVATE_KEY_CACHE, "sm/private.key");
		String publicKeyStr = KeyStoreUtil.getKeyFromResources(SM_PUBLIC_KEY_CACHE, "sm/public.key");
		
		if(StringUtils.isBlank(privateKeyStr) || StringUtils.isBlank(publicKeyStr)) {
    		throw new FileNotFoundException("file: sm/private.key and sm/public.key not exist!");
    	}

		sm2 = SmUtil.sm2(Base64.decode(privateKeyStr), Base64.decode(publicKeyStr));
		//放入缓存
		SM2_MAP.put(SM_KEY_DEFAULT_CACHE, sm2);
		
		return sm2;
	}

}
